import {
  Button,
  Checkbox,
  CheckboxGroup,
  Modal,
  ModalProps,
  Pagination,
  PaginationProps,
  Radio,
  RadioGroup,
  Table
} from 'ant-design-vue'
import type { ColumnType } from 'ant-design-vue/lib/table/interface'
import { tableProps } from 'ant-design-vue/lib/table/Table'
import {
  defineComponent,
  ExtractPropTypes,
  PropType,
  Ref,
  ref,
  renderSlot
} from 'vue'
import { findAndRemove } from '../../utils/array'
import { SingleValueType, ValueType } from '../../utils/types'

export type TableProps = ReturnType<typeof tableProps>

export interface TagAttr {
  key: string
  label: string
}

export type TableAttrs = Omit<TableProps, 'columns' | 'dataSource'> & {
  columns: ColumnType[]
}

const spsTableSelectProps = {
  value: {
    type: [String, Number, Array] as PropType<ValueType>
  },
  options: {
    type: Array as PropType<any[]>,
    default: () => []
  },
  dataProp: {},
  multiple: {
    type: Boolean,
    default: false
  },
  tableAttrs: {
    type: Object as PropType<TableAttrs>,
    require: true
  },
  modalAttrs: {
    type: Object as PropType<Partial<ModalProps>>
  },
  paginationAttrs: {
    type: Object as PropType<PaginationProps>
  },
  'onUpdate:value': {
    type: Function as PropType<(value: ValueType) => void>
  },
  pageChange: {
    type: Function as PropType<(page: number, pageSize: number) => void>
  }
} as const

export type SpsTableSelectProps = Partial<
  ExtractPropTypes<typeof spsTableSelectProps>
>

export default defineComponent({
  name: 'SpsTableSelect',
  props: spsTableSelectProps,
  emits: ['onUpdate:value', 'pageChange'],
  setup(props, { slots, emit }) {
    // console.log(props)
    const visible = ref(false)
    const model = ref<ValueType>(props.value || [])
    const displayTags = ref<TagAttr[]>([])
    const selectedOptions = ref<any[]>([])
    const checkboxModel = ref<SingleValueType[]>([])
    const handleCheckboxChange = (e: any, record: any) => {
      const {
        target: { checked }
      } = e
      if (checked) {
        selectedOptions.value.push(record)
      } else {
        selectedOptions.value = findAndRemove(selectedOptions.value, record.id)
      }
    }
    const handlePageChange = async (page: number, pageSize: number) => {
      const { multiple, pageChange } = props
      pageChange && (await pageChange(page, pageSize))
      if (multiple) {
        const current = selectedOptions.value
        checkboxModel.value = current
          .map((item) => item.id)
          .filter(
            (item) =>
              props.options.findIndex((option) => option.id === item) >= 0
          )
      }
    }
    const handleSelectSubmit = () => {
      const { multiple } = props
      if (multiple) {
        model.value = checkboxModel.value
      }
      visible.value = false
    }
    const modalContent = () => {
      const { tableAttrs, options, multiple, paginationAttrs } = props
      const tableSelectColumn: ColumnType = {
        dataIndex: 'SPS_TABLE_SELECT_AREA',
        width: 20,
        customRender({ record }) {
          return multiple ? (
            //@ts-ignore
            <Checkbox
              value={record.id}
              onChange={(e) => handleCheckboxChange(e, record)}
            />
          ) : (
            <Radio value={record.id} />
          )
        }
      }
      const { columns, ...otherAttrs } = tableAttrs!
      const tableContent = (
        //@ts-ignore
        <Table
          columns={[tableSelectColumn, ...columns]}
          {...otherAttrs}
          pagination={false}
          dataSource={options}
        />
      )
      const paginationContent = (
        <Pagination
          {...paginationAttrs}
          onChange={(page, pageSize) => handlePageChange(page, pageSize)}
        />
      )
      return multiple ? (
        <>
          <CheckboxGroup
            class="table-checkbox-group"
            v-model:value={checkboxModel.value}>
            {JSON.stringify(selectedOptions.value)}
            {JSON.stringify(checkboxModel.value)}
            {tableContent}
          </CheckboxGroup>
          {paginationContent}
        </>
      ) : (
        <>
          <RadioGroup class="table-radio-group" v-model:value={model.value}>
            {tableContent}
          </RadioGroup>
          {paginationContent}
        </>
      )
    }
    /* render 函数 */
    return () => {
      return (
        <div class="sps-table-select">
          {model.value}
          <Button
            type="primary"
            shape="round"
            onClick={() => (visible.value = true)}>
            {slots.default ? renderSlot(slots, 'default') : '请选择'}
          </Button>
          <Modal
            class="sps-table-select-modal"
            v-model:visible={visible.value}
            onOk={handleSelectSubmit}
            v-slots={{
              default: modalContent
            }}
            {...props.modalAttrs}
          />
        </div>
      )
    }
  }
})
